package com.pureut.storage.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pureut.common.core.exception.GlobalException;
import com.pureut.common.security.utils.DictUtils;
import com.pureut.common.security.utils.SecurityUtils;
import com.pureut.storage.domain.*;
import com.pureut.storage.domain.order.domain.ConverterManagement;
import com.pureut.storage.domain.order.domain.OrderSupplierManagement;
import com.pureut.storage.dto.IncomingMaterialPrintingDetailDto;
import com.pureut.storage.mapper.IncomingMaterialPrintingDetailMapper;
import com.pureut.storage.mapper.IncomingMaterialPrintingMapper;
import com.pureut.storage.mapper.IncomingMaterialSubcontractPrintingMapper;
import com.pureut.storage.mapper.PublicGoodsMapper;
import com.pureut.storage.service.*;
import com.pureut.storage.vo.DeleteDetailVo;
import com.pureut.storage.vo.IncomingMaterialPrintingVo;
import com.pureut.storage.vo.IncomingMaterialSubcontractPrintingVo;
import com.pureut.system.api.domain.SysDictData;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/***
 *
 * Author:C
 * Date:2022/12/27 11:56
 * @DESC
 */
@Service
public class IncomingMaterialPrintingDetailServiceImpl extends ServiceImpl<IncomingMaterialPrintingDetailMapper, IncomingMaterialPrintingDetail> implements IncomingMaterialPrintingDetailService {

    @Resource
    IncomingMaterialPrintingDetailMapper incomingMaterialPrintingDetailMapper;

    @Resource
    IncomingMaterialPrintingMapper incomingMaterialPrintingMapper;

    @Resource
    SubcontractReceiptDetailService subcontractReceiptDetailService;

    @Lazy
    @Resource
    IncomingMaterialPrintingService incomingMaterialPrintingService;

    @Resource
    PurchaseReceiptDetailService purchaseReceiptDetailService;

    @Resource
    OrderSupplierManagementService orderSupplierManagementService;

    @Resource
    WmsStockInfoService wmsStockInfoService;

    @Lazy
    @Resource
    IncomingMaterialSubcontractPrintingService incomingMaterialSubcontractPrintingService;

    @Resource
    IncomingMaterialSubcontractPrintingMapper incomingMaterialSubcontractPrintingMapper;

    @Resource
    ConverterManagementService converterManagementService;

    @Resource
    PublicGoodsMapper publicGoodsMapper;

    /**
     * 采购打印明细列表
     *
     * @param id
     * @return
     */
    @Override
    public List<IncomingMaterialPrintingDetailDto> getDetailList(long id) {

        return incomingMaterialPrintingDetailMapper.getDetailList(id);
    }


    /**
     * 委外打印明细列表
     *
     * @param id
     * @return
     */
    @Override
    public List<IncomingMaterialPrintingDetailDto> getSubcontractList(long id) {

        //获取网型标准缓存字典数据
        List<SysDictData> netArray = DictUtils.getDictCache("sys_of_type");
        Map<String, String> netMap = netArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        //获取铺网类型标准缓存字典数据
        List<SysDictData> netTypeArray = DictUtils.getDictCache("sys_type_net");
        Map<String, String> netTypeMap = netTypeArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        List<IncomingMaterialPrintingDetailDto> subcontractDetailList = incomingMaterialPrintingDetailMapper.getSubcontractDetailList(id);
        for (IncomingMaterialPrintingDetailDto entity : subcontractDetailList) {
            entity.setMaterialNetDict(netMap.get(entity.getMaterialNet()));
            entity.setMaterialNetTypeDict(netTypeMap.get(entity.getMaterialNetType()));
        }
        return subcontractDetailList;
    }

    /**
     * 打印（采购）
     *
     * @param incomingMaterialPrintingVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<IncomingMaterialPrintingDetailDto> getPrint(IncomingMaterialPrintingVo incomingMaterialPrintingVo) {
        IncomingMaterialPrinting incomingMaterialPrinting = incomingMaterialPrintingService.getById(incomingMaterialPrintingVo.getId());
        //获取供应商信息
        OrderSupplierManagement orderSupplierManagement = orderSupplierManagementService.getById(incomingMaterialPrinting.getSupplierId());
        if (incomingMaterialPrinting.getPrintStatus() == 2) {
            List<IncomingMaterialPrintingDetailDto> detailList = incomingMaterialPrintingDetailMapper.getDetailList(incomingMaterialPrintingVo.getId());
            List<PurchaseReceiptDetail> purchaseReceiptDetailList = new ArrayList<>();
            List<WmsStockInfo> wmsStockInfoList = new ArrayList<>();
            for (IncomingMaterialPrintingDetailDto entity : detailList) {
                PublicGoods publicGoods = publicGoodsMapper.selectOne(new QueryWrapper<PublicGoods>().lambda().eq(PublicGoods::getMaterialCode, entity.getMaterialCode()));
                //将数据新增至采购入库明细列表
                PurchaseReceiptDetail purchaseReceiptDetail = new PurchaseReceiptDetail();
                purchaseReceiptDetail.setMaterialCode(entity.getMaterialCode())
                        .setMaterialNumber(entity.getMaterialNumber())
                        .setStatus(1)
                        .setGrossWeight(entity.getGrossWeight())
                        .setNetWeight(entity.getNetWeight())
                        .setReceiptQuantity(1)
                        .setBatchNo(entity.getBatchNo())
                        .setDateManufacture(incomingMaterialPrintingVo.getDateManufacture())
                        .setReceiptId(detailList.get(0).getReceiptId());

                purchaseReceiptDetailList.add(purchaseReceiptDetail);
                //新增相关数据到仓库表
                WmsStockInfo wmsStockInfo = new WmsStockInfo();
                wmsStockInfo.setWsiMaterialNumber(purchaseReceiptDetail.getMaterialNumber())
                        .setWsiMaterialCode(entity.getMaterialCode())
                        .setWsiMaterialType(entity.getMaterialType())
                        .setWsiCategory(String.valueOf(publicGoods.getMaterialCategory()))
                        .setWsiMaterialNum(1)
                        .setWsiMaterialStatus(1)
                        .setWsiMaterialBatch(entity.getBatchNo())
                        .setWsiGorssWeight(entity.getGrossWeight())
                        .setWsiNetWeight(entity.getNetWeight())
                        .setWsiProducedDate(incomingMaterialPrintingVo.getDateManufacture())
                        .setWsiReveiveTime(new Date())
                        .setCreateUser(SecurityUtils.getUsername())
                        .setWsiConnectNum(incomingMaterialPrinting.getReceiptNo())
                        .setCreateTime(new Date());

                if (orderSupplierManagement != null) {
                    wmsStockInfo.setWsiSupplierCode(orderSupplierManagement.getSupplierNum());
                }
                wmsStockInfoList.add(wmsStockInfo);
            }
            //修改打印明细
            List<IncomingMaterialPrintingDetail> incomingMaterialPrintingDetails = incomingMaterialPrintingDetailMapper.selectList(new QueryWrapper<IncomingMaterialPrintingDetail>().lambda().eq(IncomingMaterialPrintingDetail::getPrintId, incomingMaterialPrintingVo.getId()));
            for (IncomingMaterialPrintingDetail entry : incomingMaterialPrintingDetails) {
                entry.setDateManufacture(incomingMaterialPrintingVo.getDateManufacture());
            }
            updateBatchById(incomingMaterialPrintingDetails);
            //保存到采购入库明细
            purchaseReceiptDetailService.saveBatch(purchaseReceiptDetailList);
            //保存数据到仓库表
            wmsStockInfoService.saveBatch(wmsStockInfoList);
            //修改采购打印状态为待入库
            incomingMaterialPrinting.setPrintStatus(3);
            incomingMaterialPrinting.setPrintedQuantity(detailList.size());
            incomingMaterialPrinting.setPrintBy(SecurityUtils.getUsername());
            incomingMaterialPrinting.setPrintTime(new Date());
            incomingMaterialPrintingService.updateById(incomingMaterialPrinting);
            return detailList;
        } else {
            throw new GlobalException("只能操作待打印的数据");
        }
    }

    /**
     * 委外打印
     *
     * @param incomingMaterialSubcontractPrintingVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<IncomingMaterialPrintingDetailDto> subcontractPrint(IncomingMaterialSubcontractPrintingVo incomingMaterialSubcontractPrintingVo) {
        IncomingMaterialSubcontractPrinting subcontractPrint = incomingMaterialSubcontractPrintingService.getById(incomingMaterialSubcontractPrintingVo.getId());
        //获取加工商信息
        ConverterManagement converterManagement = converterManagementService.getById(subcontractPrint.getConverterId());
        if (subcontractPrint.getPrintStatus() == 2) {
            List<IncomingMaterialPrintingDetailDto> subcontractDetailList = incomingMaterialPrintingDetailMapper.getSubcontractDetailList(subcontractPrint.getId());
            //同时完善打印明细信息
            List<IncomingMaterialPrintingDetail> incomingMaterialPrintingDetails = incomingMaterialPrintingDetailMapper.selectList(new QueryWrapper<IncomingMaterialPrintingDetail>().lambda().eq(IncomingMaterialPrintingDetail::getSubcontractId, subcontractDetailList.get(0).getSubcontractId()));
            List<IncomingMaterialPrintingDetail> incomingMaterialPrintingDetailList = new ArrayList<>();
            for (IncomingMaterialPrintingDetail entity : incomingMaterialPrintingDetails) {
                entity.setDateManufacture(incomingMaterialSubcontractPrintingVo.getDateManufacture());
                entity.setWidthCloth(incomingMaterialSubcontractPrintingVo.getWidthCloth());
                entity.setRollLength(incomingMaterialSubcontractPrintingVo.getRollLength());
                entity.setThickness(incomingMaterialSubcontractPrintingVo.getThickness());
                incomingMaterialPrintingDetailList.add(entity);
            }
            updateBatchById(incomingMaterialPrintingDetailList);

            List<SubcontractReceiptDetail> subcontractReceiptDetailList = new ArrayList<>();
            List<WmsStockInfo> wmsStockInfoList = new ArrayList<>();
            for (IncomingMaterialPrintingDetailDto entity : subcontractDetailList) {
                //将委外打印数据保存到委外入库明细列表
                SubcontractReceiptDetail subcontractReceiptDetail = new SubcontractReceiptDetail();
                subcontractReceiptDetail.setMaterialNumber(entity.getMaterialNumber())
                        .setMaterialCode(subcontractPrint.getMaterialCode())
                        .setStatus(1)
                        .setGrossWeight(entity.getGrossWeight())
                        .setNetWeight(entity.getNetWeight())
                        .setReceiptQuantity(1)
                        .setBatchNo(entity.getBatchNo())
                        .setSubcontractId(incomingMaterialPrintingDetails.get(0).getReceiptId());
                subcontractReceiptDetailList.add(subcontractReceiptDetail);
                //新增数据到仓库表
                PublicGoods publicGoods = publicGoodsMapper.selectOne(new QueryWrapper<PublicGoods>().lambda().eq(PublicGoods::getMaterialCode, entity.getMaterialCode()));
                WmsStockInfo wmsStockInfo = new WmsStockInfo();
                wmsStockInfo.setWsiMaterialNumber(subcontractReceiptDetail.getMaterialNumber())
                        .setWsiMaterialCode(entity.getMaterialCode())
                        .setWsiMaterialType(publicGoods.getMaterialType())
                        .setWsiCategory(String.valueOf(publicGoods.getMaterialCategory()))
                        .setWsiMaterialNum(1)
                        .setWsiMaterialStatus(1)
                        .setWsiMaterialBatch(entity.getBatchNo())
                        .setWsiGorssWeight(entity.getGrossWeight())
                        .setWsiNetWeight(entity.getNetWeight())
                        .setWsiConverterCode(converterManagement.getConverterNum())
                        .setWsiProducedDate(incomingMaterialSubcontractPrintingVo.getDateManufacture())
                        .setWsiReveiveTime(new Date())
                        .setCreateUser(SecurityUtils.getUsername())
                        .setCreateTime(new Date())
                        .setWsiWidth(String.valueOf(incomingMaterialSubcontractPrintingVo.getWidthCloth()))
                        .setWsiLength(String.valueOf(incomingMaterialSubcontractPrintingVo.getRollLength()))
                        .setWsiThick(incomingMaterialSubcontractPrintingVo.getThickness());
                wmsStockInfoList.add(wmsStockInfo);
            }
            subcontractReceiptDetailService.saveBatch(subcontractReceiptDetailList);
            //保存数据到仓库表
            wmsStockInfoService.saveBatch(wmsStockInfoList);
            //修改采购打印状态为待入库
            subcontractPrint.setPrintStatus(3);
            subcontractPrint.setPrintedQuantity(subcontractDetailList.size());
            subcontractPrint.setPrintBy(SecurityUtils.getUsername());
            subcontractPrint.setPrintTime(new Date());
            incomingMaterialSubcontractPrintingService.updateById(subcontractPrint);
            return subcontractDetailList;
        } else {
            throw new GlobalException("只能操作待打印的数据");
        }
    }


    /**
     * 来料打印页面对应的号码全部删除，上表的打印状态更新为“已完成”
     *
     * @param deleteDetailVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteDetail(DeleteDetailVo deleteDetailVo) {

        //获取明细列表
        List<IncomingMaterialPrintingDetail> incomingMaterialPrintingDetails = incomingMaterialPrintingDetailMapper.selectList(new QueryWrapper<IncomingMaterialPrintingDetail>().lambda().in(IncomingMaterialPrintingDetail::getMaterialNumber, deleteDetailVo.getMaterialNumberList()));

        //判断是否采购打印数据
        IncomingMaterialPrinting incomingMaterialPrinting = incomingMaterialPrintingMapper.selectOne(new QueryWrapper<IncomingMaterialPrinting>().lambda().eq(IncomingMaterialPrinting::getId, incomingMaterialPrintingDetails.get(0).getPrintId()));
        if (incomingMaterialPrinting != null && incomingMaterialPrinting.getReceiptNo() != null) {
            //并将明细删除
            incomingMaterialPrintingDetailMapper.deleteBatchIds(incomingMaterialPrintingDetails);
            //同时删除上方单据
            return incomingMaterialPrintingService.removeById(incomingMaterialPrinting);
        }

        IncomingMaterialSubcontractPrinting incomingMaterialSubcontractPrinting = incomingMaterialSubcontractPrintingMapper.selectOne(new QueryWrapper<IncomingMaterialSubcontractPrinting>().lambda().eq(IncomingMaterialSubcontractPrinting::getId, incomingMaterialPrintingDetails.get(0).getSubcontractId()));
        if (incomingMaterialSubcontractPrinting != null) {
            //并将明细删除
            incomingMaterialPrintingDetailMapper.deleteBatchIds(incomingMaterialPrintingDetails);
            //同时删除上方单据
            return incomingMaterialSubcontractPrintingService.removeById(incomingMaterialSubcontractPrinting);
        }
        return false;
    }

    /**
     * 删除来料打印页面数据（fegin调用）
     *
     * @param deleteDetailVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteData(DeleteDetailVo deleteDetailVo) {

        //获取明细列表
        List<IncomingMaterialPrintingDetail> incomingMaterialPrintingDetails = incomingMaterialPrintingDetailMapper.selectList(new QueryWrapper<IncomingMaterialPrintingDetail>().lambda().in(IncomingMaterialPrintingDetail::getMaterialNumber, deleteDetailVo.getMaterialNumberList()));

        //判断是否采购打印数据
        IncomingMaterialPrinting incomingMaterialPrinting = incomingMaterialPrintingMapper.selectOne(new QueryWrapper<IncomingMaterialPrinting>().lambda().eq(IncomingMaterialPrinting::getId, incomingMaterialPrintingDetails.get(0).getPrintId()));
        if (incomingMaterialPrinting != null) {
            //并将明细删除
            return incomingMaterialPrintingDetailMapper.deleteBatchIds(incomingMaterialPrintingDetails) > 0;
//                return incomingMaterialPrintingMapper.deleteById(incomingMaterialPrinting) > 0;
        }
        IncomingMaterialSubcontractPrinting incomingMaterialSubcontractPrinting = incomingMaterialSubcontractPrintingMapper.selectOne(new QueryWrapper<IncomingMaterialSubcontractPrinting>().lambda().eq(IncomingMaterialSubcontractPrinting::getId, incomingMaterialPrintingDetails.get(0).getSubcontractId()));
        if (incomingMaterialSubcontractPrinting != null) {
            //并将明细删除
            return incomingMaterialPrintingDetailMapper.deleteBatchIds(incomingMaterialPrintingDetails) > 0;
//            return incomingMaterialSubcontractPrintingMapper.deleteById(incomingMaterialSubcontractPrinting) > 0;
        }
            return false;
        }
    }
